<template>
	<view class="v-table-container">
		<view class="v-table">
			<view class="v-table-header" @click="handleHeaderClick">
				<view class="v-table-header-cell" v-for="(column, index) in columns" :key="index" :style="{ width: column.width , flex:  '1 1 0%'}">
					{{ column.label }}
					<view v-if="column.prop && sortable" class="sort-icon">
						<text class="arrow-up" :class="{ active: column.prop === sortConfig.prop && sortConfig.order === 'asc' }">↑</text>
						<text class="arrow-down" :class="{ active: column.prop === sortConfig.prop && sortConfig.order === 'desc' }">↓</text>
					</view>
				</view>
			</view>
			<view class="v-table-body">
				<view v-if="!data.length" class="empty-data">
					<slot name="empty">暂无数据</slot>
				</view>
				<view class="v-table-row" v-for="(row, rowIndex) in sortedData" :key="rowIndex">
					<view class="v-table-cell" v-for="(column, colIndex) in columns" :key="colIndex" :style="{ width: column.width , flex:  '1 1 0%'}">
						<slot :name="`cell-${column.prop}`" :row="row" :column="column" :index="rowIndex">
							{{ row[column.prop] }}
						</slot>
					</view>
				</view>
			</view>
		</view>
	</view>
</template>

<script lang="ts" setup>
import { computed, ref ,inject} from 'vue';

interface TableColumn {
	prop: string;
	label: string;
	width?: string;
}

interface SortConfig {
	prop: string | null;
	order: 'asc' | 'desc' | null;
}

/**
 * v-table
 * columns 表格列配置
 *        prop 表格列绑定的数据属性名
 *        label 表格列标题
 *        width 表格列宽度
 * data 表格数据数组
 * sortable 是否支持排序 默认值:false 可选值true支持排序、false不支持排序
 */
const props = defineProps({
	columns: {
		type: Array,
		default: () => [],
		required: true
	},
	data: {
		type: Array,
		default: () => []
	},
	sortable: {
		type: Boolean,
		default: false
	}
});

const config = inject<any>('config');
const sortConfig = ref<SortConfig>({
	prop: null,
	order: null
});

const sortedData = computed(() => {
	if (!props.sortable || !props.data.length || !sortConfig.value.prop) {
		return props.data;
	}

	return [...props.data].sort((a, b) => {
		const aValue = a[sortConfig.value.prop];
		const bValue = b[sortConfig.value.prop];

		if (sortConfig.value.order === 'asc') {
			return aValue > bValue ? 1 : -1;
		} else {
			return aValue < bValue ? 1 : -1;
		}
	});
});

const handleHeaderClick = (event: any) => {
	const target = event.target;
	const columnName = target.closest('.v-table-header-cell');
	if (!columnName) return;

	const columnProp = props.columns.find((col, index) => {
		const cell = target.closest('.v-table-header-cell');
		return cell && cell.getAttribute('data-index') === index.toString();
	}).prop;

	if (!columnProp) return;

	if (sortConfig.value.prop === columnProp) {
		sortConfig.value.order = sortConfig.value.order === 'asc' ? 'desc' : 'asc';
	} else {
		sortConfig.value.prop = columnProp;
		sortConfig.value.order = 'asc';
	}
};
</script>

<style lang="scss" scoped>
.v-table-container {
	width: 100%;
	border-radius: 8rpx;
	overflow: hidden;
	box-shadow: 0 2rpx 12rpx 0 rgba(0, 0, 0, 0.1);
	border: 1rpx solid v-bind("config.border.color");
}

.v-table {
	width: 100%;
	box-sizing: border-box;
}

.v-table-header {
	display: flex;
	background-color: v-bind("config.VTable.backgroundColor");
	border-bottom: 1rpx solid v-bind("config.border.color");
}

.v-table-header-cell {
	padding: 12rpx 16rpx;
	font-weight: bold;
	color: v-bind("config.fontColor.mianTitle");
	text-align: left;
	box-sizing: border-box;
	border-right: 1rpx solid v-bind("config.border.color");
	cursor: pointer;
	position: relative;
	user-select: none;
}

.v-table-header-cell:hover {
	background-color: v-bind("config.VTable.backgroundColor");
}

.sort-icon {
	display: inline-block;
	margin-left: 5rpx;
	vertical-align: middle;
}

.arrow-up,
.arrow-down {
	display: block;
	font-size: v-bind("config.fontSize.smallText");
	color: v-bind("config.fontColor.text");
	margin: 0 2rpx;
}

.arrow-up.active,
.arrow-down.active {
	color: v-bind("config.fontColor.default");
}

.v-table-body {
	display: flex;
	flex-direction: column;
}

.v-table-row {
	display: flex;
	border-bottom: 1rpx solid v-bind("config.border.color");
	transition: background-color 0.3s;
}

.v-table-row:hover {
	background-color: v-bind("config.VTable.backgroundColor");
}

.v-table-row:last-child {
	border-bottom: none;
}

.v-table-row:nth-child(even) {
	background-color: #v-bind("config.VTable.backgroundColor");
}

.v-table-cell {
	padding: 12px 16px;
	color: v-bind("config.fontColor.text");
	text-align: left;
	box-sizing: border-box;
	border-right: 1rpx solid v-bind("config.border.color");
}

.empty-data {
	padding: 20rpx;
	text-align: center;
	color: v-bind("config.fontColor.text");
}
</style>
